﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.Drawing;
using Grid.Extensions;
using System.Xml;
using System.IO;

namespace Grid.Extensions
{
	public static class GridExtensions
	{
		public static Dictionary<Type, Type> MapColumns =  new Dictionary<Type,Type>
		{
			{ typeof(string), typeof(DataGridViewTextBoxColumn) },
			{ typeof(bool), typeof(DataGridViewCheckBoxColumn) },
			{ typeof(Font), typeof(DataGridViewFontColumn) },
			{ typeof(Color), typeof(DataGridViewColorColumn) },
			{ typeof(DateTime), typeof(CalendarColumn) },
			{ typeof(TimeSpan), typeof(DataGridViewTimeSpanColumn) },
			{ typeof(int), typeof(DataGridViewNumericColumn) }
			
		};
		
		public static Dictionary<Type, Func<DataGridViewColumn, PropertyInfo, DataGridViewColumn>> CustomMapColumns =
			new Dictionary<Type,Func<DataGridViewColumn,PropertyInfo, DataGridViewColumn>>
		{
			{typeof(CalendarColumn), (dg_column, p) =>
				{
					DateTimeFormatAttribute attr = p.GetCustomAttributes(
						typeof(DateTimeFormatAttribute), false).
						Cast<DateTimeFormatAttribute>().First();
					if (attr != null)
					{
						((CalendarColumn)dg_column).DateTimeFormat= attr.Format;
						((CalendarColumn)dg_column).CustomFormat = attr.CustomFormat;
					}
					else
					{
						((CalendarColumn)dg_column).DateTimeFormat = DateTimePickerFormat.Short;	
					}
					return dg_column;			
				}	 
			},
			{typeof(DataGridViewNumericColumn), (dg_column, p) =>
				{
					NumericFormatAttribute attr = p.GetCustomAttributes(typeof(NumericFormatAttribute), false).
						Cast<NumericFormatAttribute>().FirstOrDefault();
					if (attr != null)
					{
						((DataGridViewNumericColumn)dg_column).MinValue = attr.MinValue;
						((DataGridViewNumericColumn)dg_column).MaxValue = attr.MaxValue;
					}
					else
					{
						((DataGridViewNumericColumn)dg_column).MinValue = 0;
						((DataGridViewNumericColumn)dg_column).MaxValue = 100;
					}
					return dg_column;
				}
			
			}
		};
			
		public static void SetDGSource<T>(this DataGridView dg, BindingList<T> data)
		{
			dg.AutoGenerateColumns = false;
			dg.Columns.Clear();
			if (data == null || data.Count == 0)
			{
				dg.DataSource = null;
				return;
			}
			dg.DataSource = data;
			
			DataGridViewColumn dg_column;
			foreach (PropertyInfo p in typeof(T).GetProperties())
			{
				if ((p.GetCustomAttributes(typeof(DisplayNameAttribute),false)).Length != 0)
				{
					if (MapColumns.ContainsKey(p.PropertyType))
					{
						dg_column = Activator.CreateInstance(MapColumns[p.PropertyType]) as DataGridViewColumn;
						if (CustomMapColumns.ContainsKey(dg_column.GetType()))
							dg_column = CustomMapColumns[dg_column.GetType()](dg_column, p);
						dg_column.DataPropertyName = p.Name;
						dg_column.HeaderText = ((DisplayNameAttribute)p.
							GetCustomAttributes(typeof(DisplayNameAttribute), false).First()).DisplayName;
						dg.Columns.Add(dg_column);
					}
					else
						throw new Exception("There no DataGridViewColumn extension realized type '" + 
							p.PropertyType + @"' in model, sorry. But YOU may call Iaroslav and ask him 
							for THIS type extension, maybe he helps you ;)");
				}
			}
			
		}
		
		public static void SetDGSource<T>(this DataGridView dg, BindingList<T> data, string[] col_width)
		{
			dg.SetDGSource<T>(data);
			for (int i = 0; i < dg.ColumnCount; i++)
				dg.Columns[i].Width = Convert.ToInt32(col_width[i]);
		}

	}
}